package com.ruoyi.service.impl;

import com.ruoyi.domain.Article;
import com.ruoyi.mapper.ArticleMapper;
import com.ruoyi.service.ArticleService;
import org.dromara.x.file.storage.core.FileInfo;
import org.dromara.x.file.storage.core.FileStorageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentLinkedQueue;

@Service
public class PdfParseTaskServiceImpl {

    @Autowired
    private ArticleService articleService;

    @Autowired
    private ArticleMapper articleMapper;

    @Autowired
    private FileStorageService fileStorageService;

    /**
     * 异步处理PDF解析任务
     * @param articleId 文章ID
     */
    @Async("pdfParseTaskExecutor")
    public void processPdfParseTask(Long articleId) {
        try {
            System.out.println("开始处理PDF解析任务，文章ID: " + articleId);
            if (articleId != null) {
                // 查询文章信息
                Article article = articleService.selectArticleByArticleId(articleId);
                if (article != null) {
                    System.out.println("找到文章，附件URL: " + article.getAttachment());
                    // 解析PDF并更新文章
                    parsePdfToImages(article);
                } else {
                    System.out.println("未找到文章，文章ID: " + articleId);
                }
            } else {
                System.out.println("文章ID为空，不处理PDF解析任务");
            }
        } catch (Exception e) {
            System.err.println("处理PDF解析任务失败，文章ID: " + articleId + ", 错误: " + e.getMessage());
        }
    }

    /**
     * 解析PDF文件为图片并保存到pdfImagePaths字段
     */
    private void parsePdfToImages(Article article) {
        try {
            System.out.println("开始解析PDF文件，文章ID: " + article.getArticleId());
            // 检查文章是否有附件且附件是PDF文件
            String attachmentUrl = article.getAttachment();
            System.out.println("附件URL: " + attachmentUrl);
            if (attachmentUrl == null || attachmentUrl.isEmpty()) {
                System.out.println("附件URL为空，不进行PDF解析");
                return;
            }

            // 检查附件URL是否指向PDF文件（简单检查文件扩展名）
            if (!attachmentUrl.toLowerCase().endsWith(".pdf")) {
                System.out.println("附件不是PDF文件，不进行PDF解析");
                return;
            }

            System.out.println("确认是PDF文件，开始下载并解析");

            // 从OSS下载PDF文件
            try {
                java.net.URL url = new java.net.URL(attachmentUrl);
                // 设置连接超时和读取超时
                java.net.HttpURLConnection connection = (java.net.HttpURLConnection) url.openConnection();
                connection.setConnectTimeout(5000); // 5秒连接超时
                connection.setReadTimeout(30000);   // 30秒读取超时

                // 检查响应码
                if (connection.getResponseCode() == java.net.HttpURLConnection.HTTP_OK) {
                    try (java.io.InputStream inputStream = connection.getInputStream()) {
                        // 将InputStream转换为MultipartFile或直接处理
                        parsePdfInputStreamToImages(article, inputStream);
                        // 更新文章以保存PDF图片路径
                        articleMapper.updateArticle(article);
                    }
                } else {
                    System.err.println("下载PDF文件失败，HTTP响应码: " + connection.getResponseCode());
                }
                connection.disconnect();
            } catch (Exception e) {
                System.err.println("下载PDF文件失败: " + e.getMessage());
            }

        } catch (Exception e) {
            System.err.println("PDF解析失败: " + e.getMessage());
        }
    }

    /**
     * 解析PDF输入流为图片并保存到pdfImagePaths字段
     */
    private void parsePdfInputStreamToImages(Article article, InputStream pdfInputStream) {
        try {
            // 1. PDF转图片（处理所有页）
            org.apache.pdfbox.pdmodel.PDDocument document = org.apache.pdfbox.pdmodel.PDDocument.load(pdfInputStream);
            int totalPages = document.getNumberOfPages();
            if (totalPages == 0) {
                document.close();
                return;
            }

            org.apache.pdfbox.rendering.PDFRenderer renderer = new org.apache.pdfbox.rendering.PDFRenderer(document);
            List<String> imageUrls = new ArrayList<>(); // 存储所有页图片URL
            String basePath = "article/pdf-images/"; // OSS基础路径
            String uuid = com.ruoyi.common.utils.uuid.UUID.randomUUID().toString(); // 生成唯一ID用于关联同PDF的多页图片

            // 循环处理每一页
            for (int pageNum = 0; pageNum < totalPages; pageNum++) {
                // 渲染当前页（1.5f=缩放比例，值越大清晰度越高）
                java.awt.image.BufferedImage image = renderer.renderImage(pageNum, 1.5f);

                // 2. 图片转为输入流
                ByteArrayOutputStream os = new ByteArrayOutputStream();
                boolean writeSuccess = javax.imageio.ImageIO.write(image, "png", os);
                if (!writeSuccess) {
                    document.close(); // 确保关闭文档
                    return;
                }
                InputStream imageInputStream = new ByteArrayInputStream(os.toByteArray());

                // 3. 上传当前页图片至OSS（文件名包含页号，避免冲突）
                String fileName = uuid + "_page" + (pageNum + 1) + ".png"; // 格式：uuid_page1.png
                String objectName = basePath + LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));

                FileInfo fileInfo = fileStorageService.of(imageInputStream)
                        .setPlatform("aliyun-oss-1")
                        .setPath(objectName)
                        .setOriginalFilename(fileName)
                        .setContentType("image/png")
                        .upload();

                if (fileInfo == null || fileInfo.getUrl() == null) {
                    document.close();
                    return;
                }
                imageUrls.add(fileInfo.getUrl()); // 直接使用上传后的URL
            }
            document.close(); // 所有页处理完毕后关闭文档

            // 4. 存储多图片URL至数据库（逗号分隔）
            article.setPdfImagePaths(String.join(",", imageUrls));
            System.out.println("文章PDF图片：" + article.getPdfImagePaths());
        } catch (Exception e) {
            System.err.println("PDF解析失败: " + e.getMessage());
        }
    }
}